package com.lucy.nepu.module.paper.listener;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import com.lucy.common.utils.JsonUtil;
import com.lucy.flow.domain.dto.FlowParam;
import com.lucy.flow.domain.entity.FlowWork;
import com.lucy.flow.event.FlowWorkEndEvent;
import com.lucy.flow.service.FlowWorkCtl;
import com.lucy.flow.service.FlowWorkService;
import com.lucy.nepu.constant.ResearchTypeConst;
import com.lucy.nepu.data.workload.constant.WorkloadSourceConst;
import com.lucy.nepu.data.workload.constant.WorkloadTypeConst;
import com.lucy.nepu.data.workload.entity.Workload;
import com.lucy.nepu.data.workload.service.WorkloadService;
import com.lucy.nepu.module.book.lib.BookDictService;
import com.lucy.nepu.module.book.service.BookService;
import com.lucy.nepu.module.htopic.constant.HorTopicConst;
import com.lucy.nepu.module.htopic.entity.HorTopic;
import com.lucy.nepu.module.htopic.event.HorTopicCreatedEvent;
import com.lucy.nepu.module.htopic.event.HorTopicDeletedEvent;
import com.lucy.nepu.module.htopic.lib.HorTopicDict;
import com.lucy.nepu.module.paper.constant.PaperConst;
import com.lucy.nepu.module.paper.entity.Paper;
import com.lucy.nepu.module.paper.event.PaperCreatedEvent;
import com.lucy.nepu.module.paper.event.PaperDeletedEvent;
import com.lucy.nepu.module.paper.lib.PaperDict;
import com.lucy.nepu.module.paper.lib.PaperDictService;
import com.lucy.nepu.module.paper.service.PaperService;
import com.lucy.nepu.system.period.Period;
import com.lucy.nepu.system.period.PeriodService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.Map;

/**
 * @author kindear
 * 流程操作相关监听器
 */
@Slf4j
@Service(PaperConst.TYPE)
public class FlowListener {
    @Autowired
    FlowWorkCtl flowWorkCtl;

    @Autowired
    FlowWorkService flowWorkService;

    @Autowired
    WorkloadService workloadService;

    @Autowired
    PaperService service;

    @Autowired
    PaperDictService dictService;

    @Autowired
    PeriodService periodService;

    /**
     * 监听课题创建事件
     * @param event 监听事件
     */
    @Async("threadExecutor")
    @EventListener(PaperCreatedEvent.class)
    public void paperCreatedEvent(PaperCreatedEvent event){
        Paper paper = event.getPaper();
        // 1. 构建流程参数
        FlowParam flowParam = new FlowParam();
        flowParam.setBizType(ResearchTypeConst.PAPER);
        flowParam.setBizId(paper.getId());
        // Bean 转 map
        Map<String, Object> map = BeanUtil.beanToMap(paper);
        flowParam.setParams(map);
        // 2. 获取当前登录信息
        String operator = StpUtil.getLoginIdAsString();
        // 3. 启动流程
        FlowWork flowWork = flowWorkCtl.startProcess(PaperConst.FLOW_DEFINE_CODE,operator,flowParam);
        log.debug("流程实例:{}已启动",flowWork.getId());
    }

    /**
     * 监听课题删除事件
     * @param event 监听事件
     */
    @Async("threadExecutor")
    @EventListener(PaperDeletedEvent.class)
    public void paperDeletedEvent(PaperDeletedEvent event){
        Paper paper = event.getPaper();
        String bizId = paper.getId();
        FlowWork flowWork = flowWorkService.getByBizId(bizId);
        // 删除流程实例
        flowWorkService.deleteOne(flowWork.getId());
    }

    @Async("threadExecutor")
    @EventListener(value = FlowWorkEndEvent.class,condition = "#event.flowWork.bizType == '论文'")
    public void workEndEvent(FlowWorkEndEvent event){
        FlowWork flowWork = event.getFlowWork();
        // 1. 获取实例ID
        String bizId = flowWork.getBizId();
        // 2. 获取实例信息
        Paper entity = service.getOneUnwrap(bizId);
        // 3. 获取词典
        String dictId = entity.getPaperDictId();
        PaperDict dict = dictService.getOneUnwrap(dictId);
        // 4. 初始化工作量记录信息
        Workload workload = new Workload();
        // 4. 构建附加信息
        String attach = JsonUtil.obj2String(entity);
        workload.setWorkloadAttach(attach);
        // 5. 关联ID
        workload.setLinkId(bizId);
        // 6. 类型
        String bizType = flowWork.getBizType();
        workload.setWorkloadType(bizType);
        // 7. 工作量来源
        workload.setWorkloadSource(WorkloadSourceConst.APPLY);
        // 设置工作量类型 -- 科研工作量
        workload.setWorkloadType(WorkloadTypeConst.RESEARCH);
        // 8. 工作量级别
        String level = dict.getPaperLevel();
        workload.setWorkloadLevel(level);
        // 9. 设置周期
        String periodId = entity.getPeriodId();
        Period period = periodService.getOneUnwrap(periodId);
        workload.setPeriodId(periodId);
        workload.setParentPeriodId(period.getParentId());
        // 10. 设置用户ID
        Long userId = entity.getSecondAuthorId();
        if (!entity.getFirstAuthorId().equals(0L)) userId = entity.getFirstAuthorId();
        workload.setUserId(userId);
        // 11. 工作量
        workload.setWorkload(entity.getWorkload());
        // 12. 已使用工作量
        workload.setUsedWorkload(0.0);
        // 13. 未用
        workload.setUsedUp(0);
        // 14. 工作量锁
        workload.setWorkloadLock(2);
        // 15. 备注信息
        String remark = entity.getPaperTitle();
        workload.setRemark(remark);

        // 写入
        workloadService.saveOne(workload);
    }
}
